package com.jic.member.impl;

import com.alibaba.fastjson.JSONObject;
import com.beust.jcommander.internal.Sets;
import com.google.common.collect.Lists;
import com.jic.common.base.vo.Page;
import com.jic.common.base.vo.PageResult;
import com.jic.common.base.vo.RestResult;
import com.jic.common.utils.IDUtils;
import com.jic.manager.api.manage.SysDeptApi;
import com.jic.member.entity.*;
import com.jic.member.enums.CardPeriodTypeEnum;
import com.jic.member.exception.BussinessExcetionEnum;
import com.jic.member.mapper.*;
import com.jic.member.request.*;
import com.jic.member.response.MemDiscountCardHistoryResponse;
import com.jic.member.response.MemDiscountCardResponse;
import com.jic.member.response.MememberUserForMarketResponse;
import com.jic.member.response.MememberUserResponse;
import com.jic.member.service.GenerateCardService;
import com.jic.member.service.MemDiscountCardService;
import com.jic.member.service.MememberUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;


/**
 * 折扣卡
 * @since : 2020-07-02
 * @author MJ
 */
@Service
@Slf4j
public class MemDiscountCardServiceImpl implements MemDiscountCardService {
    //线程池

    private static Integer PARTITION_NUM = 8000;

    @Autowired
    MemDiscountCardPeriodEntityMapper memDiscountCardPeriodEntityMapper;

    @Autowired
    MemDiscountCardEntityMapper memDiscountCardEntityMapper;

    @Autowired
    MemDiscountThemeEntityMapper memDiscountThemeEntityMapper;

    @Autowired
    MemDiscountCardActionRecordEntityMapper memDiscountCardActionRecordEntityMapper;

    @Autowired
    MememberUserMapper mememberUserMapper;

    @Autowired
    MememberUserService mememberUserService;

    @Autowired
    GenerateCardService generateCardService;

    @Autowired
    SysDeptApi sysDeptService;



    @Override
    public RestResult<String> generateDiscountCard(MemDiscountCardGenerateRequest request) {
        long start = System.currentTimeMillis();
        MemDiscountThemeEntity entity = memDiscountThemeEntityMapper.queryById(request.getDiscountThemeId());
        MemDiscountCardPeriodEntity memDiscountCardPeriodEntity = new MemDiscountCardPeriodEntity();
        memDiscountCardPeriodEntity.setDiscountThemeId(request.getDiscountThemeId());
        memDiscountCardPeriodEntity.setDiscountThemeName(entity.getDiscountThemeName());
        memDiscountCardPeriodEntity.setPeriodNum(request.getPeriodNum());
        memDiscountCardPeriodEntity.setPeriodType(CardPeriodTypeEnum.GENERATE_TYPE.getType());
        memDiscountCardPeriodEntity.setCreator(request.getAdminOperate().getOperator());
        memDiscountCardPeriodEntity.setCreatorName(request.getAdminOperate().getOperateName());
        memDiscountCardPeriodEntity.setUpdater(request.getAdminOperate().getOperator());
        memDiscountCardPeriodEntity.setUpdaterName(request.getAdminOperate().getOperateName());
        memDiscountCardPeriodEntity.setDeleteFlag(0);
        memDiscountCardPeriodEntityMapper.insert(memDiscountCardPeriodEntity);
        entity.setStatus(2);
        memDiscountThemeEntityMapper.update(entity);
        int periodNum = (null == request.getPeriodNum()) ? 0 : request.getPeriodNum();
        List<MemDiscountCardEntity> list = new ArrayList<>();
        for (int i = 0; i< periodNum; i++){
            MemDiscountCardEntity memDiscountCardEntity = new MemDiscountCardEntity();
            memDiscountCardEntity.setDiscountThemeId(request.getDiscountThemeId());
            memDiscountCardEntity.setDiscountThemeName(entity.getDiscountThemeName());
            memDiscountCardEntity.setDiscountCardPeriodId(memDiscountCardPeriodEntity.getId());
            memDiscountCardEntity.setDiscountCardCode(IDUtils.GenerateBillNo());
            memDiscountCardEntity.setStatus(1);
            memDiscountCardEntity.setCreator(request.getAdminOperate().getOperator());
            memDiscountCardEntity.setCreatorName(request.getAdminOperate().getOperateName());
            memDiscountCardEntity.setUpdater(request.getAdminOperate().getOperator());
            memDiscountCardEntity.setUpdaterName(request.getAdminOperate().getOperateName());
            memDiscountCardEntity.setDeleteFlag(0);
            list.add(memDiscountCardEntity);
        }
        try {
            generateCardService.processGennerCode(list,memDiscountCardPeriodEntity);
        } catch (Exception e) {
            log.error("generateDiscountCard processGennerCode error: ", e);
            memDiscountCardPeriodEntity.setPeriodNum(0);
            memDiscountCardPeriodEntityMapper.update(memDiscountCardPeriodEntity);
        }
        log.info("generateDiscountCard cost = {}", System.currentTimeMillis() - start);
        return RestResult.success("正在生成折扣卡，请稍候");
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void processGennerCode(List<MemDiscountCardEntity> list){
        List<List<MemDiscountCardEntity>> partitions = Lists.partition(list, PARTITION_NUM);
        final CountDownLatch countDownLatch = new CountDownLatch(partitions.size());
        for (List<MemDiscountCardEntity> partition : partitions) {
            memDiscountCardEntityMapper.foreachInsert(partition);
        }
    }

    @Override
    public List<MemDiscountCardHistoryResponse> discountCardHistory(MemDiscountCardRequest request) {
        List<MemDiscountCardHistoryResponse> memDiscountCardHistoryResponses = new ArrayList<>();
        //根据thirdUserId获取绑定的折扣卡
        MemDiscountCardEntity param = new MemDiscountCardEntity();
        param.setStatus(2);
        param.setDeleteFlag(0);
        param.setMemberUserId(request.getMemberUserId());
        List<MemDiscountCardEntity> all = memDiscountCardEntityMapper.findAll(param);
        if(CollectionUtils.isNotEmpty(all)){
            memDiscountCardHistoryResponses = all.stream().map(card->{
                //获取主题基础配置
                MemDiscountThemeEntity memDiscountThemeEntity = memDiscountThemeEntityMapper.queryById(card.getDiscountThemeId());
                //获取所属组织
                String deptName = sysDeptService.queryDeptNameById(memDiscountThemeEntity.getDeptId()).getData();
                MemDiscountCardHistoryResponse response = new MemDiscountCardHistoryResponse()
                        .setId(card.getId())
                        .setDiscountCardCode(card.getDiscountCardCode())
                        .setDiscountThemeId(card.getDiscountThemeId())
                        .setDiscountThemeName(card.getDiscountThemeName())
                        .setCreateTime(card.getUpdateTime())//取更新时间
                        .setStartTime(memDiscountThemeEntity.getStartTime())
                        .setEndTime(memDiscountThemeEntity.getEndTime())
                        .setDiscountValue(memDiscountThemeEntity.getDiscountValue())
                        .setDeptName(deptName)
                        ;
                return response;
            }).collect(Collectors.toList());
        }
        return memDiscountCardHistoryResponses;
    }


    /**
     * 获取折扣卡列表
     * @param request
     * @return
     */
    @Override
    public PageResult<MemDiscountCardResponse> queryDiscountCardList(MemDiscountCardRequest request) {
        MemDiscountCardEntity query = new MemDiscountCardEntity();
        query.setDiscountThemeId(request.getDiscountThemeId());
        query.setStatus(request.getStatus());
        query.setDeleteFlag(0);
        query.setDiscountCardCode(StringUtils.isBlank(request.getDiscountCardCode()) ? null : request.getDiscountCardCode());
        //根据用户昵称和用户账号查询用户列表
        if(StringUtils.isNotBlank(request.getUserAccount()) || StringUtils.isNotBlank(request.getNickName())){
            MememberUser mememberUser = new MememberUser();
            mememberUser.setNickName(request.getNickName());
            mememberUser.setUserAccount(request.getUserAccount());
            List<MememberUser> mememberUsers = mememberUserMapper.query(mememberUser);
            if(CollectionUtils.isEmpty(mememberUsers)){
                return new PageResult<MemDiscountCardResponse>(){{
                    setRows(null);
                    setTotal(0);
                }};
            }
            query.setMemberUserIds(mememberUsers.stream().map(MememberUser::getId).collect(Collectors.toList()));
        }
        Page page=new Page();
        page.setStart((request.getStart()-1)*request.getLimit());
        page.setLimit(request.getLimit());
        List<MemDiscountCardEntity> ofPage = memDiscountCardEntityMapper.findOfPage(query, page);
        List<MemDiscountCardResponse> collect = ofPage.stream().map(x -> {
            MemDiscountCardResponse response = new MemDiscountCardResponse();
            if(x.getStatus() == 2){
                MememberUser mememberUser = mememberUserMapper.queryByPrimaryKey(x.getMemberUserId());
                if(mememberUser != null){
                    response.setUserAccount(mememberUser.getUserAccount());
                    response.setNickName(mememberUser.getNickName());
                    response.setDeptId(mememberUser.getDeptId());
                }
            }
            BeanUtils.copyProperties(x, response);
            return response;
        }).collect(Collectors.toList());
        int total = memDiscountCardEntityMapper.countOfPage(query);
        return new PageResult<MemDiscountCardResponse>(){{
            setRows(collect);
            setTotal(total);
        }};
    }


    @Override
    @Transactional
    public Integer bindingOrUntieDiscountCard(MemDiscountCardBindingRequest request) {
        Integer actionType = request.getActionType();
        //判断卡片是否被绑定
        MemDiscountCardEntity memDiscountCardEntity = memDiscountCardEntityMapper.queryById(request.getId());
        if(memDiscountCardEntity == null || memDiscountCardEntity.getDeleteFlag() == 1){
            throw BussinessExcetionEnum.BINDING_ERROR.buildException();
        }

        //绑卡绑卡是否已经绑定
        if(actionType == 1){
            if(memDiscountCardEntity.getStatus() == 2){
                throw BussinessExcetionEnum.BINDED_ERROR.buildException();
            }
            MemDiscountCardEntity param = new MemDiscountCardEntity();
            param.setDiscountThemeId(request.getDiscountThemeId());
            param.setDeleteFlag(0);
            param.setMemberUserId(request.getMemberUserId());
            param.setStatus(2);
            if(memDiscountCardEntityMapper.countOfPage(param) > 0){
                throw BussinessExcetionEnum.BIND_ERROR.buildException();
            }
        }

        //解绑判断是否是同一个用户
        if(actionType == 2 && !memDiscountCardEntity.getMemberUserId().equals(request.getMemberUserId())){
            throw BussinessExcetionEnum.UNITE_ERROR.buildException();
        }

        //绑定需要设置用户ID
        if(actionType == 1){
            memDiscountCardEntity.setMemberUserId(request.getMemberUserId());
        }
        //插入绑卡解绑批次表
        MemDiscountThemeEntity entity = memDiscountThemeEntityMapper.queryById(memDiscountCardEntity.getDiscountThemeId());
        MemDiscountCardPeriodEntity memDiscountCardPeriodEntity = new MemDiscountCardPeriodEntity();
        memDiscountCardPeriodEntity.setDiscountThemeId(memDiscountCardEntity.getDiscountThemeId());
        memDiscountCardPeriodEntity.setDiscountThemeName(entity.getDiscountThemeName());
        memDiscountCardPeriodEntity.setStatus(2);
        if(actionType == 1){
            memDiscountCardPeriodEntity.setPeriodType(CardPeriodTypeEnum.BINDING_TYPE.getType());
        }else if(actionType == 2){
            memDiscountCardPeriodEntity.setPeriodType(CardPeriodTypeEnum.UNTIE_TYPE.getType());
        }
        memDiscountCardPeriodEntity.setPeriodNum(0);
        memDiscountCardPeriodEntityMapper.insert(memDiscountCardPeriodEntity);

        //执行更新折扣卡表和插入操作记录表
        int update = processBindingOrUniteDiscountCard(memDiscountCardPeriodEntity.getId(), actionType, memDiscountCardEntity);

        //更新批次数量
        if(update > 0){
            MemDiscountCardPeriodEntity updatePeriod = new MemDiscountCardPeriodEntity();
            updatePeriod.setId(memDiscountCardPeriodEntity.getId());
            updatePeriod.setPeriodNum(1);
            memDiscountCardPeriodEntityMapper.update(updatePeriod);
        }else{
            throw BussinessExcetionEnum.BINDING_ERROR.buildException();
        }

        return update;
    }

    private int processBindingOrUniteDiscountCard(Long periodId, Integer actionType, MemDiscountCardEntity memDiscountCardEntity) {
        //绑定解绑操作
        MemDiscountCardEntity updateParam = new MemDiscountCardEntity();
        updateParam.setId(memDiscountCardEntity.getId());
        if(actionType == 1){
            updateParam.setMemberUserId(memDiscountCardEntity.getMemberUserId());
            updateParam.setStatus(2);
            updateParam.setOldStatus(1);
        }else if(actionType == 2){
            //updateParam.setThirdUserId(null);
            //updateParam.setMemberUserId(null);
            updateParam.setStatus(1);
            updateParam.setOldStatus(2);
        }
        int update = memDiscountCardEntityMapper.updateByIdAndStatus(updateParam);
        if(update > 0){
            //插入操作记录表
            MemDiscountCardActionRecordEntity memDiscountCardActionRecordEntity = new MemDiscountCardActionRecordEntity();
            memDiscountCardActionRecordEntity.setDiscountCardPeriodId(periodId);
            memDiscountCardActionRecordEntity.setActionType(actionType);
            memDiscountCardActionRecordEntity.setDiscountThemeId(memDiscountCardEntity.getDiscountThemeId());
            memDiscountCardActionRecordEntity.setDiscountCardId(memDiscountCardEntity.getId());
            memDiscountCardActionRecordEntity.setMemberUserId(memDiscountCardEntity.getMemberUserId());
            memDiscountCardActionRecordEntityMapper.insert(memDiscountCardActionRecordEntity);
        }
        return update;
    }

    /**
     * 批量绑定或者解绑折扣卡
     * @param request
     * @return
     */
    @Transactional
    @Override
    public Long batchBindingOrUntieDiscountCard(MemDiscountCardBatchBindingRequest request) {
        final AtomicInteger atomicInteger = new AtomicInteger(0);
        final Integer actionType = request.getActionType();
        final Long discountThemeId = request.getDiscountThemeId();
//        final Pagination pagination = Pagination.build(1, 1);
        //插入绑卡解绑批次表
        MemDiscountThemeEntity entity = memDiscountThemeEntityMapper.queryById(request.getDiscountThemeId());
        MemDiscountCardPeriodEntity memDiscountCardPeriodEntity = new MemDiscountCardPeriodEntity();
        memDiscountCardPeriodEntity.setDiscountThemeId(request.getDiscountThemeId());
        memDiscountCardPeriodEntity.setDiscountThemeName(entity.getDiscountThemeName());
        memDiscountCardPeriodEntity.setStatus(1);
        if(actionType == 1){
            memDiscountCardPeriodEntity.setPeriodType(CardPeriodTypeEnum.BINDING_TYPE.getType());
        }else if(actionType == 2){
            memDiscountCardPeriodEntity.setPeriodType(CardPeriodTypeEnum.UNTIE_TYPE.getType());
        }
        memDiscountCardPeriodEntity.setPeriodNum(atomicInteger.intValue());
        memDiscountCardPeriodEntityMapper.insert(memDiscountCardPeriodEntity);


        //根据条件查询出用户 TODO
        MememberUserForMarketRequest mememberUserForMarketRequest = new MememberUserForMarketRequest();
        List<MememberUserForMarket> memberParams = new ArrayList<>();
        for (MemDiscountCardBindingMemberQueryRequest memberQuery : request.getMemberQuerys()) {
            if(CollectionUtils.isEmpty(memberQuery.getMemberTypes()) && CollectionUtils.isEmpty(memberQuery.getMemberGradeIds())){
                continue;
            }
            MememberUserForMarket mememberUserForMarket = new MememberUserForMarket();
            mememberUserForMarket.setDeptIds(new Long[]{memberQuery.getDeptId()});
            if(CollectionUtils.isNotEmpty(memberQuery.getMemberTypes())){
                Long[] memberTypes = new Long[]{};
                mememberUserForMarket.setMemberTypes(memberQuery.getMemberTypes().stream().map(Long::parseLong).collect(Collectors.toList()).toArray(memberTypes));
            }
            if(CollectionUtils.isNotEmpty(memberQuery.getMemberGradeIds())){
                Long[] memberGradeIds = new Long[]{};
                mememberUserForMarket.setMemberGradeIds(memberQuery.getMemberGradeIds().stream().map(Long::parseLong).collect(Collectors.toList()).toArray(memberGradeIds));
            }
            memberParams.add(mememberUserForMarket);
        }
        mememberUserForMarketRequest.setParam(memberParams);
        List<MememberUserForMarketResponse> listRestResult = mememberUserService.listMemberUserInfoForMarket(mememberUserForMarketRequest).getData();
        log.info("batchBindingOrUntieDiscountCard param = {}, resulet = {}", JSONObject.toJSONString(mememberUserForMarketRequest), JSONObject.toJSONString(listRestResult));
        if(CollectionUtils.isEmpty(listRestResult)){
            log.info("batchBindingOrUntieDiscountCard 查询会员中心无数据");
            return 0L;
        }

        final Set<MememberUserResponse> memberUsers = Sets.newHashSet();
        listRestResult.forEach(l->{
            List<MememberUserResponse> mememberUserResponseList = l.getMememberUserResponseList();
            if(CollectionUtils.isNotEmpty(mememberUserResponseList)){
                mememberUserResponseList.forEach(m->{
                    memberUsers.add(m);
                });
            }
        });

        if(CollectionUtils.isNotEmpty(memberUsers)){
            for (MememberUserResponse memberUser : memberUsers) {
                //解绑
                if(actionType == 2){
                    MemDiscountCardEntity memDiscountCardEntity = new MemDiscountCardEntity();
                    memDiscountCardEntity.setStatus(2);
                    memDiscountCardEntity.setDeleteFlag(0);
                    memDiscountCardEntity.setMemberUserId(memberUser.getId());
                    memDiscountCardEntity.setDiscountThemeId(discountThemeId);
                    List<MemDiscountCardEntity> all = memDiscountCardEntityMapper.findAll(memDiscountCardEntity);
                    if(CollectionUtils.isEmpty(all)){
                        continue;
                    }
                    int update = memDiscountCardEntityMapper.untieByMemberIdAndThemeId(memberUser.getId(), discountThemeId);
                    if(update > 0){
                        atomicInteger.addAndGet(1);
                        //插入执行记录
                        MemDiscountCardActionRecordEntity memDiscountCardActionRecordEntity = new MemDiscountCardActionRecordEntity();
                        memDiscountCardActionRecordEntity.setDiscountCardPeriodId(memDiscountCardPeriodEntity.getId());
                        memDiscountCardActionRecordEntity.setActionType(actionType);
                        memDiscountCardActionRecordEntity.setDiscountThemeId(all.get(0).getDiscountThemeId());
                        memDiscountCardActionRecordEntity.setDiscountCardId(all.get(0).getId());
                        memDiscountCardActionRecordEntity.setMemberUserId(all.get(0).getMemberUserId());
                        memDiscountCardActionRecordEntityMapper.insert(memDiscountCardActionRecordEntity);
                    }



                }else {
                    MemDiscountCardEntity memDiscountCardEntity = new MemDiscountCardEntity();
                    memDiscountCardEntity.setStatus(2);
                    memDiscountCardEntity.setDeleteFlag(0);
                    memDiscountCardEntity.setMemberUserId(memberUser.getId());
                    memDiscountCardEntity.setDiscountThemeId(discountThemeId);
                    //判断次用户是否已经绑定过
                    if(memDiscountCardEntityMapper.countOfPage(memDiscountCardEntity) > 0){
                        continue;
                    }
                    //查询是否还有未绑定对卡片
                    MemDiscountCardEntity queryNoBinding = new MemDiscountCardEntity();
                    queryNoBinding.setDeleteFlag(0);
                    queryNoBinding.setStatus(1);
                    queryNoBinding.setDiscountThemeId(discountThemeId);
                    List<MemDiscountCardEntity> ofPage = memDiscountCardEntityMapper.findOfPage(queryNoBinding, new Page());
                    if(CollectionUtils.isEmpty(ofPage)){
                        break;
                    }
                    //绑卡
                    MemDiscountCardEntity bindingParam = new MemDiscountCardEntity();
                    bindingParam.setMemberUserId(memberUser.getId());
                    bindingParam.setStatus(2);
                    bindingParam.setOldStatus(1);
                    bindingParam.setId(ofPage.get(0).getId());
                    int update = memDiscountCardEntityMapper.updateByIdAndStatus(bindingParam);
                    if(update > 0){
                        atomicInteger.addAndGet(1);
                        //插入执行记录
                        MemDiscountCardActionRecordEntity memDiscountCardActionRecordEntity = new MemDiscountCardActionRecordEntity();
                        memDiscountCardActionRecordEntity.setDiscountCardPeriodId(memDiscountCardPeriodEntity.getId());
                        memDiscountCardActionRecordEntity.setActionType(actionType);
                        memDiscountCardActionRecordEntity.setDiscountThemeId(ofPage.get(0).getDiscountThemeId());
                        memDiscountCardActionRecordEntity.setDiscountCardId(ofPage.get(0).getId());
                        memDiscountCardActionRecordEntity.setMemberUserId(memberUser.getId());
                        memDiscountCardActionRecordEntityMapper.insert(memDiscountCardActionRecordEntity);
                    }
                }
            }
        }

        //更新期次执行结果
        MemDiscountCardPeriodEntity updatePeriod = new MemDiscountCardPeriodEntity();
        updatePeriod.setId(memDiscountCardPeriodEntity.getId());
        updatePeriod.setPeriodNum(atomicInteger.intValue());
        updatePeriod.setStatus(2);
        memDiscountCardPeriodEntityMapper.update(updatePeriod);

        return atomicInteger.longValue();
    }

    @Override
    public MemDiscountCardResponse queryBindingOrNoCount(MemDiscountCardBatchBindingRequest request) {
        MemDiscountCardEntity memDiscountCardEntity = new MemDiscountCardEntity();
        memDiscountCardEntity.setDiscountThemeId(request.getDiscountThemeId());
        memDiscountCardEntity.setDeleteFlag(0);
        memDiscountCardEntity.setStatus(1);
        int noBindingCount = memDiscountCardEntityMapper.countOfPage(memDiscountCardEntity);
        memDiscountCardEntity.setStatus(2);
        int bindingCount = memDiscountCardEntityMapper.countOfPage(memDiscountCardEntity);
        return  new MemDiscountCardResponse()
                .setNoBindingTotal(noBindingCount)
                .setBindingTotal(bindingCount);
    }
}
